home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / Dylan Related / Mindy / Mindy 1.2 - portable sources / comp / mindycomp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-15  |  7.1 KB  |  341 lines  |  [TEXT/ttxt]

  1. /**********************************************************************\
  2. *
  3. *  Copyright (c) 1994  Carnegie Mellon University
  4. *  All rights reserved.
  5. *  
  6. *  Use and copying of this software and preparation of derivative
  7. *  works based on this software are permitted, including commercial
  8. *  use, provided that the following conditions are observed:
  9. *  
  10. *  1. This copyright notice must be retained in full on any copies
  11. *     and on appropriate parts of any derivative works.
  12. *  2. Documentation (paper or online) accompanying any system that
  13. *     incorporates this software, or any part of it, must acknowledge
  14. *     the contribution of the Gwydion Project at Carnegie Mellon
  15. *     University.
  16. *  
  17. *  This software is made available "as is".  Neither the authors nor
  18. *  Carnegie Mellon University make any warranty about the software,
  19. *  its performance, or its conformity to any specification.
  20. *  
  21. *  Bug reports, questions, comments, and suggestions should be sent by
  22. *  E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  23. *
  24. ***********************************************************************
  25. *
  26. * $Header: mindycomp.c,v 1.11 94/11/28 07:16:16 wlott Exp $
  27. *
  28. * This file is the main driver.
  29. *
  30. \**********************************************************************/
  31.  
  32. #include "../compat/std-c.h"
  33. #include "../compat/std-os.h"
  34.  
  35. #include "mindycomp.h"
  36. #include "parser.h"
  37. #include "src.h"
  38. #include "print.h"
  39. #include "expand.h"
  40. #include "envanal.h"
  41. #include "lexer.h"
  42. #include "header.h"
  43. #include "sym.h"
  44. #include "info.h"
  45. #include "compile.h"
  46. #include "dump.h"
  47.  
  48. struct body *Program = NULL;
  49.  
  50. struct symbol *LibraryName = NULL;
  51. struct symbol *ModuleName = NULL;
  52. boolean GiveWarnings = TRUE;
  53.  
  54. char *current_file = "<stdin>";
  55.  
  56. static int nerrors = 0;
  57.  
  58. static void verror(int line, char *msg, va_list ap)
  59. {
  60.     fprintf(stderr, "%s:%d: error: ", current_file, line);
  61.     vfprintf(stderr, msg, ap);
  62.     if (msg[strlen(msg)-1] != '\n')
  63.     putc('\n', stderr);
  64.  
  65.     nerrors++;
  66. }
  67. #if _USING_PROTOTYPES_
  68. void error(int line, char *msg, ...)
  69. {
  70.     va_list ap;
  71.  
  72.     va_start(ap, msg);
  73.     verror(line, msg, ap);
  74.     va_end(ap);
  75. }
  76. #else
  77. void error(va_alist) va_dcl
  78. {
  79.     va_list ap;
  80.     int line;
  81.     char *msg;
  82.  
  83.     va_start(ap);
  84.     line = va_arg(ap, int);
  85.     msg = va_arg(ap, char *);
  86.     verror(line, msg, ap);
  87.     va_end(ap);
  88. }
  89. #endif
  90.  
  91. static void vwarn(int line, char *msg, va_list ap)
  92. {
  93.     if ( ! GiveWarnings)
  94.         return;
  95.     fprintf(stderr, "%s:%d: warning: ", current_file, line);
  96.     vfprintf(stderr, msg, ap);
  97.     if (msg[strlen(msg)-1] != '\n')
  98.     putc('\n', stderr);
  99. }
  100.  
  101. #if _USING_PROTOTYPES_
  102. void warn(int line, char *msg, ...)
  103. {
  104.     va_list ap;
  105.  
  106.     va_start(ap, msg);
  107.     vwarn(line, msg, ap);
  108.     va_end(ap);
  109. }
  110. #else
  111. void warn(va_alist) va_dcl
  112. {
  113.     va_list ap;
  114.     int line;
  115.     char *msg;
  116.  
  117.     va_start(ap);
  118.     line = va_arg(ap, int);
  119.     msg = va_arg(ap, char *);
  120.     vwarn(line, msg, ap);
  121.     va_end(ap);
  122. }
  123. #endif
  124.  
  125. static void usage(void)
  126. {
  127.     fprintf(stderr, "usage: mindycomp [-d[p][e]] [-l library-name] "
  128.         "[-o object-name] source-name\n");
  129.     exit(1);
  130. }
  131.  
  132. static void set_module(char *value)
  133. {
  134.     if (ModuleName) {
  135.     fprintf(stderr, "multiple module: file headers.\n");
  136.     exit(1);
  137.     }
  138.     ModuleName = symbol(value);
  139. }
  140.  
  141. static void set_library(char *value)
  142. {
  143.     if (LibraryName && strcasecmp(LibraryName->name, value)) {
  144.     fprintf(stderr,
  145.         "Library name specified on the command line differs from\n"
  146.         "the library name specified in the file.\n");
  147.     exit(1);
  148.     }
  149.     free(LibraryName);
  150.     LibraryName = symbol(value);
  151. }
  152.  
  153. static void end_of_headers(char *value)
  154. {
  155.     if ( ! ModuleName) {
  156.         warn(line_count-1, "no module: header, assuming Dylan-User\n");
  157.     ModuleName = sym_DylanUser;
  158.     }
  159. }
  160.  
  161. static char *find_extension(char *source)
  162. {
  163.     char *slash = strrchr(source, '/');
  164.     char *dot = strchr(slash ? slash : source, '.');
  165.  
  166.     if (dot)
  167.     return dot+1;
  168.     else
  169.     return NULL;
  170. }
  171.  
  172. static char *make_output_name(char *source, char *new_extension)
  173. {
  174.     char *extension = find_extension(source);
  175.     int base_len = extension ? extension - source - 1 : strlen(source);
  176.     char *output = malloc(base_len + strlen(new_extension) + 1);
  177.  
  178.     memcpy(output, source, base_len);
  179.     strcpy(output + base_len, new_extension);
  180.  
  181.     return output;
  182. }
  183.  
  184. void main(int argc, char *argv[])
  185. {
  186.     boolean print_parse = FALSE;
  187.     boolean print_expanded = FALSE;
  188.     char *arg;
  189.     char *source_name = NULL;
  190.     char *output_name = NULL;
  191.     FILE *file;
  192.  
  193.     add_header_handler("module", set_module);
  194.     add_header_handler("library", set_library);
  195.     add_header_handler(NULL, end_of_headers);
  196.  
  197.     init_sym_table();
  198.     init_info();
  199.     init_expand();
  200.     init_compile();
  201.  
  202.     while ((arg = *++argv) != NULL) {
  203.     if (arg[0] == '-') {
  204.         switch (arg[1]) {
  205.           case 'd':
  206.         if (arg[2] == '\0') {
  207.             print_parse = TRUE;
  208.             print_expanded = TRUE;
  209.         }
  210.         else {
  211.             char *ptr;
  212.             for (ptr = arg+2; *ptr != '\0'; ptr++) {
  213.             switch (*ptr) {
  214.               case 'p':
  215.                 print_parse = TRUE;
  216.                 break;
  217.               case 'e':
  218.                 print_expanded = TRUE;
  219.                 break;
  220.               default:
  221.                 fprintf(stderr, "Invalid thing to print: ``%c''\n",
  222.                     *ptr);
  223.                 usage();
  224.             }
  225.             }
  226.         }
  227.         break;
  228.  
  229.           case 'o':
  230.         if (output_name != NULL) {
  231.             fprintf(stderr, "-o can only be used once.\n");
  232.             usage();
  233.         }
  234.         else if (arg[2] != '\0')
  235.             output_name = arg+2;
  236.         else if (*++argv == NULL) {
  237.             fprintf(stderr, "-o must be followed by the output "
  238.                 "file name.\n");
  239.             usage();
  240.         }
  241.         else
  242.             output_name = *argv;
  243.         break;
  244.  
  245.           case 'l':
  246.         if (LibraryName != NULL) {
  247.             fprintf(stderr, "-l can only be used once.\n");
  248.             usage();
  249.         }
  250.         if (arg[2] != '\0')
  251.             LibraryName = symbol(arg+2);
  252.         else if (*++argv == NULL) {
  253.             fprintf(stderr, "-l must be followed by the library "
  254.                 "name.\n");
  255.             usage();
  256.         }
  257.         else
  258.             LibraryName = symbol(*argv);
  259.         break;
  260.  
  261.           case 'q':
  262.         GiveWarnings = FALSE;
  263.         break;
  264.  
  265.           default:
  266.         fprintf(stderr, "Invalid flag: ``%s''\n", arg);
  267.         usage();
  268.         }
  269.     }
  270.     else if (source_name != NULL) {
  271.         fprintf(stderr, "Too many files\n");
  272.         usage();
  273.     }
  274.     else
  275.         source_name = arg;
  276.     }
  277.  
  278.     if (source_name == NULL)
  279.     usage();
  280.  
  281.  
  282.     yyin = fopen(source_name, "r");
  283.     if (yyin == NULL) {
  284.     perror(source_name);
  285.     exit(1);
  286.     }
  287.  
  288.     current_file = source_name;
  289.  
  290.     yyparse();
  291.  
  292.     if (print_parse) {
  293.     printf("================ Original Parse Tree ================\n");
  294.     print_body(Program, 0);
  295.     }
  296.  
  297.     if (nerrors != 0)
  298.     exit(1);
  299.  
  300.     /* Do the various source-to-source expansions. */
  301.     expand(Program);
  302.  
  303.     if (print_expanded) {
  304.     printf("================ Expanded Parse Tree ================\n");
  305.     print_body(Program, 0);
  306.     }
  307.  
  308.     if (nerrors != 0)
  309.     exit(1);
  310.  
  311.     /* Run environment analysis */
  312.     environment_analysis(Program);
  313.  
  314.     if (nerrors != 0)
  315.     exit(1);
  316.  
  317.     if (output_name == NULL)
  318.     output_name = make_output_name(source_name, ".dbc");
  319.  
  320.     if (strcmp(output_name, "-") == 0)
  321.         file = stdout;
  322.     else
  323.         file = fopen(output_name, "w");
  324.  
  325.     if (file == NULL) {
  326.     perror(output_name);
  327.     exit(1);
  328.     }
  329.  
  330.     dump_setup_output(source_name, file);
  331.  
  332.     /* Generate code. */
  333.     compile(Program);
  334.  
  335.     dump_finalize_output();
  336.  
  337.     fclose(file);
  338.  
  339.     exit(0);
  340. }
  341.